home *** CD-ROM | disk | FTP | other *** search
- /*
- IC Link In.c
-
- Main code for accessing the configuration file. This code can be linked in to an application
- (if the component is not available) to provide access to the IC prefs file.
-
- This code represents the lowest-level of access to the config file.
-
- History
- 11/06/95 dhn - Started C port.
- */
-
- /*
- Original pascal comment:
-
- (* File: ICLinkIn.p
- * Generated by: 1.0d4
- * For: IC 1.2
- * On: Monday, 25 September 1995, 19:28:12
- *
- * This file is part of the Internet Configuration system and
- * is placed in the public domain for the benefit of all.
- *)
- */
-
- #include <Components.h>
- #include <AppleTalk.h>
- #include <Folders.h>
- #include <Processes.h>
- #include <Errors.h>
- #include <AppleEvents.h>
- #include <LowMem.h>
-
- #include "IC Types.h"
- #include "IC Keys.h"
-
- #include "IC Resource API.h"
- #include "IC Link In Subs.h"
-
- #define kICOurManufacturer 'JPQE'
- #define kRes_Code 'ICRP'
-
- // Local Prototypes
- #ifdef __cplusplus
- extern "C" {
- #endif
-
- OSErr ICFindFolder(short vRefNum,OSType folderType,Boolean createFolder,short* foundVRefNum,long* foundDirID);
- Boolean ICRCloseIfOpen(ICRRecordPtr inst);
- ICError ValidDirSpec(ICDirSpec* folder);
- OSErr FoundFile(ICDirSpec* folder,short ndx,FSSpec* found_file);
- Boolean ScanFolder(ICRRecordPtr inst,ICDirSpec* folder,FSSpecPtr found_file);
- OSErr FindPrefFolder(ICDirSpec* pref_fold);
- void SetSFCWD(ICRRecordPtr inst);
- ICError GetFile(ICRRecordPtr inst,FSSpecPtr fs);
- ICError PutFile(ICRRecord* inst,FSSpecPtr fs);
- short ICRPermToFSPerm(ICPerm perm);
- ICError ICRCheckInside(ICRRecord* inst);
- ICError ICRForceInside(ICRRecord* inst,ICPerm perm,Boolean* force_info);
- ICError ICRReleaseInside(ICRRecord* inst,Boolean force_info);
- Boolean __URL_SpecStartChar(char ch);
- Boolean __URL_SpecEndChar(char ch);
- ICError ExpandSelection(char* datap,long len,long* selStart,long* selEnd);
- Boolean SpaceTab(char ch);
- Boolean SpaceTabRet(char ch);
- ICError ShrinkSelection(char* datap,long len,long* selStart,long* selEnd);
- ICError StripReturns(Handle urlh);
- void UnpackCopyString(Ptr* p,StringPtr s);
- OSErr UnpackEntry(Handle entries,long pos,ICMapEntry* entry,long* user_length);
- OSErr FastGetEntry(Handle entries,long pos,ICMapEntry* entry);
- void PackCopyString(ICMapEntry* entry,Ptr p,StringPtr s);
- void PackEntry(ICMapEntry* entry,Ptr p,long user_length);
- short GetShort(Ptr P);
- char UpCase(char ch);
- Boolean IsExtensionVar(StringPtr name,StringPtr ext);
-
- Boolean HasResourceFork(const FSSpec* file);
- OSErr EnsureResourceFork(const FSSpec* file);
-
- #ifdef __cplusplus
- }
- #endif
-
- /*
- HasResourceFork
- EnsureResourceFork
-
- The IC pieces have one bug (that I have found). Although they ensure that a file exists when selecting one
- (either through the Find, FindUser, FindGeneral, or SpecifyConfigFile routines), they don't ensure that the
- files have a resource fork. That means that whatever piece is specifying the file *must* get everything right.
-
- HasResourceFork and EnsureResourceFork will check the config file; if it has a resource fork, nothing is done.
- If the file doesn't have a resource fork, one will be added.
- */
- Boolean HasResourceFork(const FSSpec* spec){
- HParamBlockRec pbr;
- OSErr err;
-
- pbr.fileParam.ioCompletion=0;
- pbr.fileParam.ioVRefNum=spec->vRefNum;
- pbr.fileParam.ioFDirIndex=0;
- pbr.fileParam.ioNamePtr=(StringPtr)spec->name;
- pbr.fileParam.ioDirID=spec->parID;
-
- err=PBHGetFInfo(&pbr,false);
- if (err!=noErr)
- return false;
-
- /*
- If a file has a resource fork, even an empty one, a resource map will still exist for the file,
- therefore the ioFlRLgLen (which contains the length of the resource fork) will be some number
- greater than zero if the file has a resource fork.
- */
- return (pbr.fileParam.ioFlRLgLen>0);
- }
-
- OSErr EnsureResourceFork(const FSSpec* spec){
- HParamBlockRec pbr;
- OSErr err;
-
- pbr.fileParam.ioCompletion=0;
- pbr.fileParam.ioVRefNum=spec->vRefNum;
- pbr.fileParam.ioFDirIndex=0;
- pbr.fileParam.ioNamePtr=(StringPtr)spec->name;
- pbr.fileParam.ioDirID=spec->parID;
-
- err=PBHGetFInfo(&pbr,false);
-
- if (err==fnfErr){
- // then the file doesn't exist, but is being put in a default place so it really should be there
- } else if (err!=noErr)
- return err;
-
- if (pbr.fileParam.ioFlRLgLen<=0){
- // file doesn't have a resource fork, create one for the file
- HCreateResFile(spec->vRefNum,spec->parID,spec->name);
- return ResError();
- }
- return noErr;
- }
-
- /*
- ICFindFolder
-
- converted from the pascal wrapper function to call the FindFolder trap.
-
- Was declared as:
-
- inline $7000,$A823
- */
- OSErr ICFindFolder(short vRefNum,OSType folderType,Boolean createFolder,short* foundVRefNum,long* foundDirID){
- return FindFolder(vRefNum,folderType,createFolder,foundVRefNum,foundDirID);
- }
-
- ICError ICRStart(ICRRecordPtr inst,OSType creator){
- ICError err;
- Str255 defPrompt="\pCreate configuration as:";
-
- if (inst==(ICRRecordPtr)0)
- return (ICError)paramErr;
-
- inst->have_config_file=false;
- inst->config_file.vRefNum=0;
- inst->config_file.parID=0;
- inst->config_file.name[0]=0;
- inst->config_refnum=0;
- inst->perm=icNoPerm;
-
- BlockMoveData((Ptr)defPrompt,(Ptr)inst->prompt,defPrompt[0]+2);
-
- ICRDefaultFileName(inst,inst->default_filename);
-
- return noErr;
- }
-
- Boolean ICRCloseIfOpen(ICRRecordPtr inst){
- Boolean ret=inst->perm!=icNoPerm;
-
- if (inst->config_refnum!=0){
- CloseResFile(inst->config_refnum);
- inst->config_refnum=0;
- }
-
- inst->perm=icNoPerm;
-
- return ret;
- }
-
- ICError ICRStop(ICRRecordPtr inst){
-
- if (inst==(ICRRecordPtr)0)
- return (ICError)paramErr;
-
- if (ICRCloseIfOpen(inst))
- return (ICError)paramErr;
-
- return (ICError)noErr;
- }
-
-
- ICError ValidDirSpec(ICDirSpec* folder){
- CInfoPBRec cpb;
-
- cpb.hFileInfo.ioVRefNum=folder->vRefNum;
- cpb.hFileInfo.ioDirID=folder->dirID;
- cpb.hFileInfo.ioNamePtr=(StringPtr)0;
- cpb.hFileInfo.ioFDirIndex=-1;
-
- return (ICError)PBGetCatInfoSync(&cpb);
- }
-
- OSErr FoundFile(ICDirSpec* folder,short ndx,FSSpec* found_file){
- OSErr err;
- CInfoPBRec cpb;
- Boolean is_folder;
- Boolean was_alias;
- long response;
-
- cpb.hFileInfo.ioVRefNum=folder->vRefNum;
- cpb.hFileInfo.ioDirID=folder->dirID;
- cpb.hFileInfo.ioNamePtr=found_file->name;
- cpb.hFileInfo.ioFDirIndex=ndx;
-
- err=PBGetCatInfoSync(&cpb);
-
- if (err==noErr){
- found_file->vRefNum=cpb.hFileInfo.ioVRefNum;
- found_file->parID=cpb.hFileInfo.ioFlParID;
-
- if ((cpb.hFileInfo.ioFlAttrib&(16))||(cpb.hFileInfo.ioFlFndrInfo.fdType!=kICFileType)){
- err=(OSErr)1;
- } else if ((Gestalt(gestaltAliasMgrAttr,&response)==noErr)&&(BitTst(&response,(31-gestaltAliasMgrPresent)))){
- err=ResolveAliasFile(found_file,true,&is_folder,&was_alias);
-
- if (err!=noErr)
- err=(OSErr)1;
- }
- }
-
- return err;
- }
-
- Boolean ScanFolder(ICRRecordPtr inst,ICDirSpec* folder,FSSpecPtr found_file){
- ICError err;
- Boolean found;
- register short i;
-
- BlockMoveData((Ptr)inst->default_filename,(Ptr)found_file->name,inst->default_filename[0]+1);
-
- found=(FoundFile(folder,0,found_file)==noErr);
-
- if (!found){
- i=1;
-
- do {
- found_file->name[0]=0;
- err=FoundFile(folder,i,found_file);
- i++;
- } while (err!=1);
-
- found=(err==noErr);
- }
-
- return found;
- }
-
- ICError ICRFindConfigFile(ICRRecordPtr inst,short count,ICDirSpecArrayPtr folders){
- return ICRGeneralFindConfigFile(inst,true,true,count,folders);
- }
-
- ICError ICRFindUserConfigFile(ICRRecordPtr inst,ICDirSpec* where){
- return ICRGeneralFindConfigFile(inst,false,true,1,where);
- }
-
- OSErr FindPrefFolder(ICDirSpec* pref_fold){
- OSErr err;
- SysEnvRec env;
- long response;
-
- err=Gestalt(gestaltFindFolderAttr,&response);
-
- if (err==noErr){
- if (BitTst(&response,(31-gestaltFindFolderPresent)))
- return ICFindFolder(kOnSystemDisk,kPreferencesFolderType,true,&(pref_fold->vRefNum),&(pref_fold->dirID));
- }
-
- // otherwise simulate FindFolder
-
- err=SysEnvirons(curSysEnvVers,&env);
-
- if (err==noErr)
- err=GetWDInfo(env.sysVRefNum,&(pref_fold->vRefNum),&(pref_fold->dirID),&response);
-
- return err;
- }
-
- ICError ICRGeneralFindConfigFile(ICRRecordPtr inst,Boolean search_prefs,Boolean can_create,short count,ICDirSpecArrayPtr folders){
- ICError err=noErr;
- register short i=0;
- Boolean found=false;
- ICDirSpec pref_fold;
- ICDirSpec* last_folder_scanned;
- FSSpec temp_config_file;
- HParamBlockRec pbr;
-
- inst->have_config_file=false;
-
- if (inst->perm!=icNoPerm)
- return (ICError)paramErr;
-
- if ((count<0)||((count!=0)&&(folders==(ICDirSpecArrayPtr)0)))
- return (ICError)paramErr;
-
- if ((count==0)&&(!search_prefs)&&(can_create))
- return (ICError)paramErr;
-
- i=0;
- while ((err==noErr)&&(i<count)){
- err=ValidDirSpec(&(folders[i]));
- i++;
- }
-
- if (err!=noErr)
- return err;
-
- i=0;
-
- while ((i<count)&&(!found)){
- found=ScanFolder(inst,&(folders[i]),&temp_config_file);
-
- last_folder_scanned=&(folders[i]);
- i++;
- }
-
- if ((!found)&&(search_prefs)){
- err=FindPrefFolder(&pref_fold);
-
- if (err==noErr){
- found=ScanFolder(inst,&pref_fold,&temp_config_file);
- last_folder_scanned=&pref_fold;
- }
- }
-
- if ((!found)&&(can_create)){
- temp_config_file.vRefNum=last_folder_scanned->vRefNum;
- temp_config_file.parID=last_folder_scanned->dirID;
- BlockMoveData((Ptr)inst->default_filename,(Ptr)temp_config_file.name,inst->default_filename[0]+1);
- found=true;
- }
-
- if (!found)
- err=icConfigNotFoundErr;
-
- if (err==noErr){
- BlockMoveData((Ptr)&(temp_config_file),(Ptr)&(inst->config_file),sizeof(FSSpec));
- inst->have_config_file=true;
-
- // Need to ensure that there is a resource fork for a file...
- err=EnsureResourceFork(&(inst->config_file));
- }
-
- return err;
- }
-
- void SetSFCWD(ICRRecordPtr inst){
-
- if (inst->have_config_file){
- LMSetCurDirStore(inst->config_file.parID);
- LMSetSFSaveDisk(-(inst->config_file.vRefNum));
- }
- }
-
- ICError GetFile(ICRRecordPtr inst,FSSpecPtr fs){
- ICError err=userCanceledErr;
- SFTypeList typeList;
- StandardFileReply nreply;
- SFReply oreply;
- long eric;
- Point where;
-
- SetSFCWD(inst);
-
- typeList[0]=kICFileType;
-
- if (HaveNewStandardFile()){
- StandardGetFile((FileFilterUPP)0,1,typeList,&nreply);
- if (nreply.sfGood){
- BlockMoveData((Ptr)&(nreply.sfFile),fs,sizeof(FSSpec));
- err=noErr;
- }
- } else {
- where.h=0x40;
- where.v=0x40;
-
- SFGetFile(where,"\p",(FileFilterUPP)0,1,typeList,(DlgHookUPP)0,&oreply);
- if (oreply.good){
- err=GetWDInfo(oreply.vRefNum,&fs->vRefNum,&fs->parID,&eric);
- BlockMoveData(oreply.fName,fs->name,oreply.fName[0]+1);
- }
- }
-
- return err;
- }
-
- ICError PutFile(ICRRecord* inst,FSSpecPtr fs){
- ICError err;
- SFTypeList typeList;
- StandardFileReply nreply;
- SFReply oreply;
- long eric;
- Str63 defname;
-
- SetSFCWD(inst);
- err=userCanceledErr;
- typeList[0]=kICFileType;
-
- if (inst->have_config_file){
- BlockMoveData(inst->config_file.name,defname,inst->config_file.name[0]+1);
- } else {
- BlockMoveData(inst->default_filename,defname,inst->default_filename[0]+1);
- }
-
- if (HaveNewStandardFile()){
- StandardPutFile(inst->prompt,defname,&nreply);
- if (nreply.sfGood){
- BlockMoveData((Ptr)&(nreply.sfFile),(Ptr)fs,sizeof(FSSpec));
- err=noErr;
- }
- } else {
- Point where;
-
- where.h=0x040;
- where.v=0x040;
-
- SFPutFile(where,inst->prompt,defname,(DlgHookUPP)0,&oreply);
- if (oreply.good){
- err=GetWDInfo(oreply.vRefNum,&fs->vRefNum,&fs->parID,&eric);
- BlockMoveData(oreply.fName,fs->name,oreply.fName[0]+1);
- }
- }
-
- return err;
- }
-
- ICError ICRChooseConfig(ICRRecord* inst){
- OSErr err=noErr;
- FSSpec config;
-
- if (inst->perm!=icNoPerm)
- return paramErr;
-
- err=CanInteract();
-
- if (err==noErr){
- err=GetFile(inst,&config);
- }
-
- if (err==noErr){
- err=ICRSpecifyConfigFile(inst,&config);
- }
-
- return err;
- }
-
- ICError ICRChooseNewConfig(ICRRecord* inst){
- OSErr err=noErr;
- FSSpec config;
-
- if (inst->perm!=icNoPerm)
- return paramErr;
-
- err=CanInteract();
-
- if (err==noErr)
- err=PutFile(inst,&config);
-
- if (err==noErr){
- HDelete(config.vRefNum,config.parID,config.name);
- err=HCreate(config.vRefNum,config.parID,config.name,kICCreator,kICFileType);
- }
-
- if (err==noErr)
- err=ICRSpecifyConfigFile(inst,&config);
-
- return err;
- }
-
- ICError ICRGetConfigName(ICRRecord* inst,Boolean longname,StringPtr name){
- OSErr err=noErr;
-
- if (!inst->have_config_file)
- return paramErr;
-
- if (!longname){
- BlockMoveData(inst->config_file.name,name,inst->config_file.name[0]+1);
- err=noErr;
- } else {
- err=FSSpecToFullPath(&(inst->config_file),name);
- }
-
- return err;
- }
-
- ICError ICRGetConfigReference(ICRRecord* inst,ICConfigRefHandle ref){
- ICError err=noErr;
- ICConfigRef header;
- long loe;
-
- if (!inst->have_config_file)
- return paramErr;
-
- if (ref==(ICConfigRefHandle)0)
- return paramErr;
-
- err=FSSpecToICFileSpec(&(inst->config_file),(ICFileSpecHandle)ref);
-
- if (err==noErr){
- header.manufacturer=kICOurManufacturer;
- loe=Munger((Handle)ref,0,(Ptr)0,0,&header,sizeof(ICConfigRef));
- err=MemError();
- }
-
- if (err!=noErr)
- SetHandleSize((Handle)ref,0);
-
- return err;
- }
-
- ICError ICRSetConfigReference(ICRRecord* inst,ICConfigRefHandle ref,long flags){
- ICError err;
- ICFileSpecHandle filespec;
- long loe;
- FSSpec fs;
-
- if (inst->perm!=icNoPerm)
- return paramErr;
-
- if (ref==(ICConfigRefHandle)0)
- return paramErr;
-
- if (GetHandleSize((Handle)ref)<4)
- return paramErr;
-
- if ((*ref)->manufacturer!=kICOurManufacturer)
- return icConfigInappropriateErr;
-
- if (GetHandleSize((Handle)ref)<(sizeof(ICConfigRef)+sizeof(ICFileSpec)))
- return paramErr;
-
- BlockMoveData((Ptr)ref,(Ptr)&filespec,sizeof(ICFileSpecHandle));
- err=HandToHand((Handle*)(&filespec));
-
- if (err==noErr){
- loe=Munger((Handle)filespec,0,(Ptr)0,sizeof(ICConfigRef),&loe,0);
- err=ICFileSpecToFSSpec(filespec,!(flags&icNoUserInteraction_mask),&fs);
- DisposeHandle((Handle)filespec);
- }
-
- if (err==noErr)
- ICRSpecifyConfigFile(inst,&fs);
-
- return err;
- }
-
- ICError ICRSpecifyConfigFile(ICRRecord* inst,FSSpecPtr config){
- ICError err;
- ICDirSpec folder;
-
- if (inst->perm!=icNoPerm)
- return paramErr;
-
- folder.vRefNum=config->vRefNum;
- folder.dirID=config->parID;
-
- err=ValidDirSpec(&folder);
-
- if (err==noErr)
- BlockMoveData((Ptr)config,(Ptr)&(inst->config_file),sizeof(FSSpec));
-
- inst->have_config_file=(err==noErr);
-
- if (inst->have_config_file){
- // Need to ensure that there is a resource fork for a file...
- err=EnsureResourceFork(&(inst->config_file));
- }
-
- return err;
- }
-
- ICError ICRGetSeed(ICRRecord* inst,long* seed){
- ICError err;
- CInfoPBRec cpb;
-
- *seed=0L;
- err=fnfErr;
-
- if (inst->have_config_file){
- cpb.hFileInfo.ioVRefNum=inst->config_file.vRefNum;
- cpb.hFileInfo.ioDirID=inst->config_file.parID;
- cpb.hFileInfo.ioNamePtr=inst->config_file.name;
- cpb.hFileInfo.ioFDirIndex=0;
-
- err=PBGetCatInfoSync(&cpb);
-
- if (err==noErr)
- *seed=cpb.hFileInfo.ioFlMdDat;
- else if (err==fnfErr)
- err=noErr;
- }
-
- return err;
- }
-
- ICError ICRGetPerm(ICRRecord* inst,ICPerm* perm){
- *perm=inst->perm;
- return noErr;
- }
-
- short ICRPermToFSPerm(ICPerm perm){
- switch (perm){
- case icReadOnlyPerm:
- return fsRdPerm;
- break;
- case icReadWritePerm:
- return fsRdWrPerm;
- break;
- default:
- return 0;
- break;
- }
-
- return 0;
- }
-
- ICError ICRBegin(ICRRecord* inst,ICPerm perm){
- ICError err;
- short ref;
-
- if ((inst->perm!=icNoPerm)||(perm==icNoPerm))
- return paramErr;
-
- if (!inst->have_config_file)
- return bdNamErr;
-
- ref=FSpOpenResFile(&(inst->config_file),ICRPermToFSPerm(perm));
- err=ResError();
-
- if ((err==fnfErr)||(err==eofErr)){
- switch (perm){
- case icReadOnlyPerm:
- ref=0;
- err=noErr;
-